package cn.ljlao.mall.product.goods.service.impl;

import cn.ljlao.common.constant.ProductConstant;
import cn.ljlao.common.dto.es.SkuEsModel;
import cn.ljlao.common.utils.R;
import cn.ljlao.mall.product.goods.entity.*;
import cn.ljlao.mall.product.goods.feign.SearchFeignService;
import cn.ljlao.mall.product.goods.feign.WareFeignService;
import cn.ljlao.mall.product.goods.feign.vo.SkuHasStockVo;
import cn.ljlao.mall.product.goods.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.ljlao.common.utils.PageUtils;
import cn.ljlao.common.utils.Query;
import cn.ljlao.mall.product.goods.dao.SpuInfoDao;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SkuInfoService skuInfoService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private ProductAttrValueService productAttrValueService;

    @Autowired
    private AttrService attrService;

    @Autowired
    private WareFeignService wareFeignService;

    @Autowired
    private SearchFeignService searchFeignService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryListInfo(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        String status = (String) params.get("status");
        String brandId = (String) params.get("brandId");
        String catelogId = (String) params.get("catelogId");
        if (!StringUtils.isEmpty(key)){
            wrapper.and(w->{
                w.eq("id",key).or().like("spu_name",key);
            });
        }
        if (!StringUtils.isEmpty(status)){
            wrapper.eq("publish_status",status);
        }

        if (!StringUtils.isEmpty(brandId)&&!"0".equals(brandId)){
            wrapper.eq("brand_id",brandId);
        }

        if (!StringUtils.isEmpty(catelogId)&&!"0".equals(catelogId)){
            wrapper.eq("catalog_id",catelogId);
        }





        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);

    }

    /**
     * 商品上架
     * @param spuId
     */
    @Override
    public void up(Long spuId) {
        // 1. 组装需要的属性
        List<SkuEsModel> upProduct = new ArrayList<>();


        //TODO 4. 查询商品的规格属性
        List<ProductAttrValueEntity> baseAttrs = productAttrValueService.listforspu(spuId); //获取所有的attrid


        List<Long> attrIds = baseAttrs.stream().map(attr -> attr.getAttrId()).collect(Collectors.toList());

        // 查询有查询条件的att
        List<Long> searchAttrs = attrService.selectSearchAttrs(attrIds);
        Set<Long> idSet = new HashSet<>(searchAttrs);

        //关联结果
        List<SkuEsModel.Attrs> attrsList = baseAttrs.stream()
                .filter(item -> idSet.contains(item.getAttrId()))
                .map(item -> {
                    SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                    BeanUtils.copyProperties(item, attrs);
                    return attrs;
                }).collect(Collectors.toList());


        //1.查出当前 spuid 对应的 sku 信息
        List<SkuInfoEntity> skus = skuInfoService.getSkusBySpuId(spuId);

        // TODO 1.发送远程调用, 库存系统查询是否有库存
        List<Long> skuIdList = skus.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        Map<Long, Boolean> map = null;
        //抽取 库存结果
        try {
            List<SkuHasStockVo> stockVos = wareFeignService.getSkusHasStock(skuIdList);
            map = stockVos.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));

        }catch (Exception e){
            log.error("库存服务异常:原因{}",e);
        }

        Map<Long, Boolean> finalMap = map;
        List<SkuEsModel> skuEsModels = skus.stream().map(sku -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(sku, skuEsModel);//属性对拷
            // 价格 图片
            skuEsModel.setSkuPrice(sku.getPrice());
            skuEsModel.setSkuImg(sku.getSkuDefaultImg());
            //设置
            if (finalMap == null) {
                skuEsModel.setHasStock(true);
            } else {
                skuEsModel.setHasStock(finalMap.get(sku.getSkuId()));
            }


            // TODO 2.热度评分 默认 0
            skuEsModel.setHotScore(0L);

            // TODO 3.查询品牌和分类的名称
            BrandEntity brand = brandService.getById(skuEsModel.getBrandId());
            skuEsModel.setBrandName(brand.getName());
            skuEsModel.setBrandImg(brand.getLogo());

            CategoryEntity category = categoryService.getById(skuEsModel.getCatalogId());
            skuEsModel.setCatalogName(category.getName());
            // 设置 attr 属性
            skuEsModel.setAttrs(attrsList);


            return skuEsModel;
        }).collect(Collectors.toList());

        // todo 5. 将数据发送 es 保存
        R r = searchFeignService.productSaveUp(skuEsModels);
        if (r.getCode()==0){
            baseMapper.updateSpuStatus(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());
        }else {
            log.error("es远程批量保存调用失败");
            //TODO 7.重复调用? 接口幂等性
        }
    }

}